//! Inve wallet

use serde_json::Value;

use crate::{
    core::chash,
    error::{Error, ErrorKind},
    mnemonic::Mnemonic,
    utils,
    wallet::Wallet,
};

#[derive(Debug, Clone)]
pub struct InveWallet {
    mnemonic: Mnemonic,
    address: String,
}

impl InveWallet {
    pub fn new(words: &str, passphrase: &str) -> Result<Self, Error> {
        let mnemonic = Mnemonic::new(words, passphrase)?;
        let address = mnemonic.get_address()?;
        Ok(Self { mnemonic, address })
    }

    pub fn address(&self) -> &str {
        &self.address
    }

    pub fn is_valid_address(address: &str) -> Result<(), Error> {
        if address.len() != 32 {
            return Err(Error::from_kind(
                ErrorKind::Msg("address length is not 32".to_string()).into(),
            ));
        }
        if &address.to_uppercase() != address {
            return Err(Error::from_kind(
                ErrorKind::Msg("address must be uppercase".to_string()).into(),
            ));
        }
        chash::is_valid_chash(address)
    }

    pub fn get_inve_address_by_definition(definition: &Value) -> Result<String, Error> {
        let source = utils::sign::get_source_string(definition)?;
        Mnemonic::get_address_by_definition(&source)
    }
}

impl Wallet for InveWallet {
    fn get_address(&self) -> String {
        self.address.clone()
    }
}
